package com.matt.service.impl;

import com.google.common.collect.ImmutableMap;
import com.matt.domain.mp.ParentUser;
import com.matt.domain.FollowLiveRoom;
import com.matt.domain.LiveRoom;
import com.matt.domain.record.CheckRecord;
import com.matt.foundation.DO.ChildrenListDO;
import com.matt.foundation.DO.LiveRoomDO;
import com.matt.foundation.constant.ChildrenConstant;
import com.matt.foundation.constant.LiveRoomConstant;
import com.matt.foundation.utils.DateUtil;
import com.matt.repository.AppUserRepository;
import com.matt.repository.FollowLiveRoomRepository;
import com.matt.repository.LiveRoomRepository;
import com.matt.repository.SystemSettingRepository;
import com.matt.repository.base.ClassesTeachingAreaRepository;
import com.matt.repository.rel.RelClassesChildrenRepository;
import com.matt.repository.rel.RelClassesTeachingAreaRepository;
import com.matt.service.AppUserService;
import com.matt.service.ChildrenService;
import com.matt.service.remoteCall.SsoCallService;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * *******************************
 * Created by Ron.
 * form com.matt
 * on 2018/10/31
 * *******************************
 */
@Service
@Slf4j
public class AppUserServiceImpl implements AppUserService {

    @Autowired
    private ChildrenService childrenService;

    @Autowired
    private RelClassesChildrenRepository relClassesChildrenRepository;

    @Autowired
    private RelClassesTeachingAreaRepository relClassesTeachingAreaRepository;

    @Autowired
    private LiveRoomRepository liveRoomRepository;

    @Autowired
    private ClassesTeachingAreaRepository classesTeachingAreaRepository;

    @Autowired
    private FollowLiveRoomRepository followLiveRoomRepository;

    @Autowired
    private SystemSettingRepository systemSettingRepository;

    @Autowired
    private SsoCallService ssoCallService;

    @Autowired
    private AppUserRepository appUserRepository;

    private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");

    private static final String SPILTER = "-";

    @Override
    public Map getAppUserLiveList(String userId) {
        List<ChildrenListDO> childrenList = childrenService.getNurseryChildByAppUser(userId);
        if (childrenList.isEmpty())
            return ImmutableMap.of("value", 200, "msg", "Sorry, 直播服务暂时只支持托班宝宝", "data", ImmutableMap.of("list", Lists.newArrayList(), "yinShiToken", "", "livePlayWay", 1));
        childrenList = childrenList.stream().filter(o -> o.getNurseryStatus() == ChildrenConstant.NurseryStatus.HAS_COURSE.codeOf()).collect(Collectors.toList());
        if (childrenList.isEmpty())
            return ImmutableMap.of("value", 200, "msg", "Sorry, 您孩子的课程可能已经结束了, 您可以到园区续费继续使用我们的服务", "data", ImmutableMap.of("list", Lists.newArrayList(), "yinShiToken", "", "livePlayWay", 1));

        List<String> childrenIds = childrenList.stream().map(o -> o.getId()).collect(Collectors.toList());
        List<String> classIds = relClassesChildrenRepository.findByChildrenIdIn(childrenIds).stream().map(o -> o.getClassesId()).collect(Collectors.toList());
        if (classIds.isEmpty())
            return ImmutableMap.of("value", 200, "msg", "您的孩子暂时没有班级, 如有需要请联系园区", "data", ImmutableMap.of("list", Lists.newArrayList(), "yinShiToken", "", "livePlayWay", 1));

        List<String> teachAreas = relClassesTeachingAreaRepository.findByClassesIdIn(classIds).stream().map(o -> o.getTeachingAreaId()).collect(Collectors.toList());
        List<LiveRoom> liveRoomList = liveRoomRepository.findByTeachingAreaIdInAndStatus(teachAreas, LiveRoomConstant.Status.LIVING.codeOf());
        if (liveRoomList.isEmpty())
            return ImmutableMap.of("value", 200, "msg", "您的孩子所在班级没有摄像头, 如有需要请联系园区", "data", ImmutableMap.of("list", Lists.newArrayList(), "yinShiToken", "", "livePlayWay", 1));

        boolean hasAnxietyTime = childrenList.stream().anyMatch(o -> (o.getAnxietyTime().longValue() + o.getCourseStartDate().getTime()) > System.currentTimeMillis());
        if (hasAnxietyTime)
            return ImmutableMap.of("value", 200, "msg", "您暂时没有权限查看, 如有需要请联系园区", "data", ImmutableMap.of("list", Lists.newArrayList(), "yinShiToken", "", "livePlayWay", 1));

        List<CheckRecord> checkRecordList = Lists.newArrayList();
        for (String childId : childrenIds) {
            CheckRecord checkRecord = childrenService.getLastCheckRecord(childId);
            if (Objects.nonNull(checkRecord))
                checkRecordList.add(checkRecord);
        }

        if (checkRecordList.isEmpty())
            return ImmutableMap.of("value", 200, "msg", "Sorry, 您的孩子尚未达到园区", "data", ImmutableMap.of("list", Lists.newArrayList(), "yinShiToken", "", "livePlayWay", 1));
        checkRecordList = checkRecordList.stream().filter(o -> Objects.isNull(o.getCheckOutTime())).collect(Collectors.toList());
        if (checkRecordList.isEmpty())
            return ImmutableMap.of("value", 200, "msg", "Sorry, 您的孩子已经离开了园区", "data", ImmutableMap.of("list", Lists.newArrayList(), "yinShiToken", "", "livePlayWay", 1));

        List<LiveRoomDO> list = classesTeachingAreaRepository.findRoomsByChildIdsIn(childrenIds);
        Map<String, String> tokenCache = new HashMap<>();

        //筛选开放时间
        list = this.matchOpenTime(list);
        //填充关注
        fillInFollow(list, userId);
        Integer livePlayWay = Integer.valueOf(systemSettingRepository.findByName("livePlayWay").getValue());
        list.stream().forEach(o->{
            String token = tokenCache.get(o.getAreaId());
            if(token == null){
                //TODO  这里需要变更
//                token = ssoCallService.getAreaYinShiToken(o.getAreaId());
//                tokenCache.put(o.getAreaId(), token);
            }
            o.setToken(token);
            o.setLivePlayWay(livePlayWay);
            o.setEzUrl(String.format(o.getEzUrl(), o.getDeviceSerial(), o.getChannelNo()));
            o.setEzHDUrl(String.format(o.getEzHDUrl(), o.getDeviceSerial(), o.getChannelNo()));
        });

        String msg = "成功";
        if(list.size() <= 0){
            msg = "当前时间段没有任何开放的摄像头, 如有疑问请联系园区！";
        }
        return ImmutableMap.of("value", 200, "msg", msg, "data", ImmutableMap.of("list", list));
    }

    @Override
    public Map getAllLiveRoomList(String allAreaId, String userId) {
        List<LiveRoom> liveRoomList = liveRoomRepository.findByAreaIdAndStatus(allAreaId, LiveRoomConstant.Status.LIVING.codeOf());
        List<LiveRoomDO> list = liveRoomList.stream().map(o->LiveRoomDO.of(o)).collect(Collectors.toList());

        Integer livePlayWay = Integer.valueOf(systemSettingRepository.findByName("livePlayWay").getValue());
        list = this.matchOpenTime(list);
        fillInFollow(list, userId);
        list.stream().forEach(o->{
            o.setLivePlayWay(livePlayWay);
            o.setEzUrl(String.format(o.getEzUrl(), o.getDeviceSerial(), o.getChannelNo()));
            o.setEzHDUrl(String.format(o.getEzHDUrl(), o.getDeviceSerial(), o.getChannelNo()));
        });
        // FIXME:
        String yinShiToken = null; //ssoCallService.getAreaYinShiToken(allAreaId);
        return ImmutableMap.of("value", 200, "msg", "成功", "data", ImmutableMap.of("list", list, "yinShiToken", yinShiToken));
    }

    private List<LiveRoomDO> fillInFollow(List<LiveRoomDO> roomList, String userId){
        List<FollowLiveRoom> followList = followLiveRoomRepository.findByUid(userId);
        for (LiveRoomDO room : roomList) {
            room.setFollow(followList.stream().anyMatch(o -> o.getLid().equals(room.getId())));
        }
        return roomList;
    }

    /**
     * @param roomDOList
     * @return 筛选开放时间
     */
    public List<LiveRoomDO> matchOpenTime(List<LiveRoomDO> roomDOList) {
        List<LiveRoomDO> finalList = Lists.newArrayList();
        Date nowDate = new Date();
        //筛选在此时间段的摄像头
        for (LiveRoomDO o : roomDOList) {
            List<String> times = Lists.newArrayList();
            try {
                times = o.ofOpenTime(o.getOpenTime());
            } catch (Exception e) {
                e.printStackTrace();
                log.error("摄像头： " + o.getName() + " 开放时间格式异常，ID为：" + o.getId());
                continue;
            }
            for (String time : times) {
                try {
                    String[] split = time.split(SPILTER);
                    if (split.length > 1) {
                        //在任意一个时间段即可
                        Date start = DateUtil.parseToDateMilis(simpleDateFormat.format(new Date()) + " " + split[0] + ":00");
                        Date end = DateUtil.parseToDateMilis(simpleDateFormat.format(new Date()) + " " + split[1] + ":59");
                        if (nowDate.getTime() >= start.getTime() && nowDate.getTime() <= end.getTime()) {
                            finalList.add(o);
                            break;
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("摄像头： " + o.getName() + " 开放时间格式异常，ID为：" + o.getId());
                    finalList.add(o);   //格式异常仍然显示 以防万一
                    break;
                }
            }
        }
        return finalList;
    }

    @Override
    public ParentUser selectByPhone(String phone) {
        return appUserRepository.findByPhone(phone);
    }
}
